package com.djc.exam.webapp.base.utils;

import cn.hutool.core.date.DatePattern;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import lombok.extern.log4j.Log4j2;

import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * @version V1.0.0
 * @date 2020/12/29 15:20
 */
@Log4j2
public class DateUtil {

    public static final String DATATIME_FORMATE = "yyyy-MM-dd HH:mm:ss.SSS";
    public static final String DATA_FORMATE = "yyyy-MM-dd HH:mm:ss";
    public static final String DATA_HOUR_FORMATE = "yyyy-MM-dd HH";
    public static final String DATATIME_MONTH_DAY_FORMATE = "MM月dd日";
    public static final String DATA_MONTH_DAY_FORMATE = "MM.dd";
    public static final String DATA_TODAY_DATE_FORMAT = "yyyy-MM-dd";
    /**
     * 根据datetime返回时间戳
     *
     * @param localDateTime
     * @return
     */
    public static long getTimestampOfDateTime(String localDateTime) {
        LocalDateTime dateTime = parseStringToDateTime(localDateTime, DATATIME_FORMATE);
        ZoneId zone = ZoneId.systemDefault();
        Instant instant = dateTime.plusHours(8).atZone(zone).toInstant();
        return instant.toEpochMilli();
    }

    public static LocalDateTime parseStringToDateTime(String time, String format) {
        DateTimeFormatter df = DateTimeFormatter.ofPattern(format);
        return LocalDateTime.parse(time, df);
    }

    public static String getFilerTime(Long days) {
        return getYesterdayByFormat(days).concat(" - ").concat(getNowByFormat());
    }

    public static String getYesterdayByFormat(Long days) {
        return LocalDateTime.now().minusDays(days).format(DateTimeFormatter.ofPattern(DATA_FORMATE));
    }

    public static String getNowByFormat() {
        return LocalDateTime.now().format(DateTimeFormatter.ofPattern(DATA_FORMATE));
    }

    public static String getNowHourByFormat() {
        return LocalDateTime.now().format(DateTimeFormatter.ofPattern(DATA_HOUR_FORMATE));
    }

    public static String getTodayDateByFormat() {
        return LocalDateTime.now().format(DateTimeFormatter.ofPattern(DATA_TODAY_DATE_FORMAT));
    }

    public static String getYesterday(){
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        Date date = new Date();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_MONTH, -1);
        date = (Date) calendar.getTime();
        String format = df.format(date);
        return format;
    }

    //获取上周开始时间
    public static Date getBeginDayOfLastWeek() {
        Date date = new Date();
        if (date == null) {
            return null;
        }
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int dayofweek = cal.get(Calendar.DAY_OF_WEEK);
        if (dayofweek == 1) {
            dayofweek += 7;
        }
        cal.add(Calendar.DATE, 2 - dayofweek - 7);
        return getDayStartTime(cal.getTime());
    }

    //获取上周的结束时间
    public static Date getEndDayOfLastWeek() {
        Calendar cal = Calendar.getInstance();
        cal.setTime(getBeginDayOfLastWeek());
        cal.add(Calendar.DAY_OF_WEEK, 6);
        Date weekEndSta = cal.getTime();
        return getDayEndTime(weekEndSta);
    }

    //获取某个日期的开始时间
    public static Timestamp getDayStartTime(Date d) {
        Calendar calendar = Calendar.getInstance();
        if (null != d) calendar.setTime(d);
        calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return new Timestamp(calendar.getTimeInMillis());
    }

    //获取某个日期的结束时间
    public static Timestamp getDayEndTime(Date d) {
        Calendar calendar = Calendar.getInstance();
        if (null != d) calendar.setTime(d);
        calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH), 23, 59, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        return new Timestamp(calendar.getTimeInMillis());
    }


    //获取上月开始时间
    public static String getLastMonthStartTime() {
        Long currentTime = System.currentTimeMillis();

        String timeZone = "GMT+8:00";
        Calendar calendar = Calendar.getInstance();// 获取当前日期
        calendar.setTimeZone(TimeZone.getTimeZone(timeZone));
        calendar.setTimeInMillis(currentTime);
        calendar.add(Calendar.YEAR, 0);
        calendar.add(Calendar.MONTH, -1);
        calendar.set(Calendar.DAY_OF_MONTH, 1);// 设置为1号,当前日期既为本月第一天
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        DateTimeFormatter ftf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        Long startTime = calendar.getTimeInMillis();
        String startTimeStr = ftf.format(LocalDateTime.ofInstant(Instant.ofEpochMilli(startTime), ZoneId.systemDefault()));
        return startTimeStr;
    }
    //获取上月结束时间
    public static String getLastMonthEndTime() {
        Long currentTime = System.currentTimeMillis();

        String timeZone = "GMT+8:00";
        Calendar calendar = Calendar.getInstance();// 获取当前日期
        calendar.setTimeZone(TimeZone.getTimeZone(timeZone));
        calendar.setTimeInMillis(currentTime);
        calendar.add(Calendar.YEAR, 0);
        calendar.add(Calendar.MONTH, -1);
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));// 获取当前月最后一天
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 999);

        Long endTime = calendar.getTimeInMillis();
        DateTimeFormatter ftf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String endTimeStr = ftf.format(LocalDateTime.ofInstant(Instant.ofEpochMilli(endTime), ZoneId.systemDefault()));
        return endTimeStr;
    }


    /**
     * @Description: 获取一段时间段List的方法
     * @Parm: DateTools.getDays(" 2020 - 02 - 27 ", " 2020 - 03 - 01 ");
     * @retrn: [2020-02-27, 2020-02-28, 2020-02-29, 2020-03-01]
     * @Autor: yyk
     * @Date: 2020/9/16
     */
    public static List<String> getDays(String startTime, String endTime) {
        // 返回的日期集合
        List<String> days = new ArrayList<String>();

        DateFormat dateFormat = new SimpleDateFormat(DatePattern.NORM_DATE_PATTERN);
        try {
            Date start = dateFormat.parse(startTime);
            Date end = dateFormat.parse(endTime);
            Calendar tempStart = Calendar.getInstance();
            tempStart.setTime(start);
            Calendar tempEnd = Calendar.getInstance();
            tempEnd.setTime(end);
            // 日期加1(包含结束)
            tempEnd.add(Calendar.DATE, +1);
            while (tempStart.before(tempEnd)) {
                days.add(dateFormat.format(tempStart.getTime()));
                tempStart.add(Calendar.DAY_OF_YEAR, 1);
            }
        } catch (ParseException e) {
            log.error("获取一段时间段List的方法失败！error:{}", e.getMessage());
        }
        return days;
    }

    /**
     * @Description: 获取两个时间节点之间的月份列表
     * @Parm: DateTools.getDays(" 2020-02-27 ", " 2020-03-01 ");
     * @retrn: [2020-02, 2020-03-28]
     * @Autor: yyk
     * @Date: 2020/9/17
     */
    public static List<String> getMonthBetween(String minDate, String maxDate){
        ArrayList<String> result = new ArrayList<String>();
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");

            Calendar min = Calendar.getInstance();
            Calendar max = Calendar.getInstance();
            min.setTime(sdf.parse(minDate));
            min.set(min.get(Calendar.YEAR), min.get(Calendar.MONTH), 1);

            max.setTime(sdf.parse(maxDate));
            max.set(max.get(Calendar.YEAR), max.get(Calendar.MONTH), 2);

            Calendar curr = min;
            while (curr.before(max)) {
                result.add(sdf.format(curr.getTime()));
                curr.add(Calendar.MONTH, 1);
            }
        } catch (ParseException e) {
            log.error("获取两个时间节点之间的月份列表失败！error:{}", e.getMessage());
        }
        return result;
    }


    /**
     * @Description: 字符串转某个格式的时间字符串
     * @Param:
     * @return:
     * @Author: zhangrui1
     * @Date: 2020/7/16
     */
    public static String format2Date(String time, String format) {
        if (StringUtils.isEmpty(time)) {
            return null;
        }
        Date date = cn.hutool.core.date.DateUtil.parse(time);
        String formatStr = cn.hutool.core.date.DateUtil.format(date, format);
        return formatStr;
    }

    /**
     * 获取某天最后时间
     * @param endTime
     * @return
     */
    public static String setEndTime(String endTime) {
        return endTime + " 23:59:59";
    }

    /**
     * 获取周的开始结束时间区间（类似这样：10.05~10.11）
     * @param date
     * @return
     */
    public static String getBetweenTimeForWeek(String date){
        Date endWeek = cn.hutool.core.date.DateUtil.endOfWeek(cn.hutool.core.date.DateUtil.parse(date));
        String endWeekTime= cn.hutool.core.date.DateUtil.format(endWeek, DateUtil.DATA_MONTH_DAY_FORMATE);
        date = cn.hutool.core.date.DateUtil.format(cn.hutool.core.date.DateUtil.parse(date), DateUtil.DATA_MONTH_DAY_FORMATE);
        return  date + "~" + endWeekTime;
    }

}
